#include "RouteInfoUploader.h"
#include "RequestBuilder.h"

namespace zeroplus::mq
{
    RouteInfoUploader::RouteInfoUploader()
        : client_(std::make_unique<ClientNode>(BrokerConfig::getInstance().clientAddr)),
          redisStore_(RedisStore::getInstance(BrokerConfig::getInstance().redisAddr))
    {
    }

    RouteInfoUploader::~RouteInfoUploader() {}

    bool RouteInfoUploader::Start()
    {
        messageLoop_.set_name("RouteInfoUploader");
        messageLoop_.register_begin_handler(std::bind(&RouteInfoUploader::SendRegisterRouteInfoRequest, this));
        messageLoop_.async_run();

        auto registerRouteInfoTimer = std::make_shared<Timer>(&messageLoop_,
                                                              NetworkFrequency::registerRouteInfoFrequency,
                                                              Timer::kInfinite,
                                                              std::bind(&RouteInfoUploader::SendRegisterRouteInfoRequest, this));

        timerList_.push_back(registerRouteInfoTimer);

        for (auto &timer : timerList_)
        {
            timer->start();
        }
    }

    bool RouteInfoUploader::Stop()
    {
        for (auto &timer : timerList_)
        {
            timer->stop();
        }
        messageLoop_.quit();
        messageLoop_.wait_for_quit();
    }

    transport::RegisterRouteInfoResponse RouteInfoUploader::SendRegisterRouteInfoRequest()
    {
        LOG_DEBUG("发送路由注册请求");
        transport::RegisterRouteInfoRequest request;
        request.set_broker_name(BrokerConfig::getInstance().brokerName);
        request.set_broker_addr(BrokerConfig::getInstance().serverAddr);
        request.set_broker_id(BrokerConfig::getInstance().brokerId);
        request.set_cluster_name(BrokerConfig::getInstance().clusterName);
        // 填充topic属性，queue属性在nameSrcv生成
        for (auto &topicName : redisStore_->GetAllTopic())
        {
            LOG_DEBUG("topicName=%s", topicName.c_str());
            int32_t queueNum = 1U;
            routeinfo::TopicData topicData;
            topicData.set_topic_name(topicName);
            topicData.set_queue_num(queueNum);
            auto topicDataTable = request.mutable_topic_data_table();
            (*topicDataTable)[topicName] = topicData;
        }

        RequestBuilder<transport::RequestCode::REGISTER_ROUTEINFO,
                       transport::RegisterRouteInfoRequest,
                       transport::RegisterRouteInfoResponse>
            builder(client_);
        auto [responseCode, response] = builder.InvokeSync(request);
        return response;
    }

    transport::UnRegisterRouteInfoResponse RouteInfoUploader::SendUnRegisterRouteInfoRequest()
    {
        LOG_INFO("not impl yet");
        transport::UnRegisterRouteInfoResponse response;
        return response;
    }

}
